#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "common.h"

static int fd = -1;

//protoSlaveType
enum _protoSlaveType
{
		_writeGPIO 			= 	0x00,
		_readGPIO			 	= 	0x01,
};

extern SystemParam* pgSystemParam;

static int writeGPIO(struct recvData *recvData, struct packageFilter *pFilter);
static int readGPIO(struct recvData *recvData, struct packageFilter *pFilter);

static int SetGpio(unsigned int key,unsigned int value);
static int GetGpio(unsigned int key);

static void* gpioStatusCheckThread(void *arg);
static void* openOutSysThread(void *arg);
static void* closeOutSysThread(void *arg);
static void* ledThread(void* arg);

static void ledShowOutSysOpening(int led);
static void ledShowOutSysClosing(int led);
static void overReturnLed(int led);
static void openLed(int led);
static void closeLed(int led);

int initGpioServer()
{
		if( fd < 0 )
				fd = open("/dev/dev_rk_gpio",O_RDWR|O_NOCTTY);
				
		pthread_t ptID;	
		if( pthread_create(&ptID, NULL, gpioStatusCheckThread, (void *)0) != 0 )
		{
				printf("create thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return -1;
		} 	
		
		if( pthread_create(&ptID, NULL, openOutSysThread, (void *)0) != 0 )
		{
				printf("create thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return -2;
		}
		
		if( pthread_create(&ptID, NULL, closeOutSysThread, (void *)0) != 0 )
		{
				printf("create thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return -3;
		}
		
		if( pthread_create(&ptID, NULL, ledThread, (void *)0) != 0 )
		{
				printf("create thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return -4;
		}
		
		return 0;
}

void gpioServer(struct recvData *recvData)
{
		if( fd < 0 )
				fd = open("/dev/dev_rk_gpio",O_RDWR|O_NOCTTY);
				
		if(fd < 0)
		{
				printf("fd < 0, fd = %d\n", fd);	
				return;
		}
		
		if(recvData == NULL)
		{
				printf("recvData == NULL ! {%s(%d)}\n",__FILE__,__LINE__);
				return;	
		}
		
		struct packageFilter filter;
		int ret = explainPackageHead(recvData, &filter);
		if(ret < 0)
		{
				return;	
		}
		
		switch(filter.protoSlaveType)
		{
				case _writeGPIO:
				{
						writeGPIO(recvData, &filter);
						break;	
				}
				case _readGPIO:
				{
						readGPIO(recvData, &filter);
						break;
				}
				default:
				{
						printf("filter.protoSlaveType not right ! filter.protoSlaveType = %d\n", filter.protoSlaveType);
						break;	
				}
		}
}

static int writeGPIO(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto 4,0 pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 6)
		{
				printf("proto 4,0 pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
		
		int ret;
		unsigned char gpioNum = pFilter->pData[0];
		if(gpioNum != 20 && gpioNum != 1 && gpioNum != 3)
		{
				printf("gpioNum != 20 || gpioNum != 1 || gpioNum != 3 ! gpioNum  = %d\n", gpioNum);	
				return -4;
		}
		
		unsigned char data = pFilter->pData[1];
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData + 2, 4);	
		printf("cmd write GPIO: gpioNum=%d, data=%d\n", gpioNum,data);
		SetGpio(gpioNum, data);
		data = (unsigned char)GetGpio(gpioNum);
		
		unsigned char dataDirection = 0x01;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, pFilter->dataLen);
		
		unsigned char checkCode = 0;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + 6;
		for(unsigned char i=0; i<headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		recvData->buf[headLen] = gpioNum;
		recvData->buf[headLen + 1] = data;
		memcpy(recvData->buf + headLen + 2, privateData, 4);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
}

static int readGPIO(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto 4,0 pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 5)
		{
				printf("proto 4,0 pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
		
		int ret;
		unsigned char gpioNum = pFilter->pData[0];
		if(gpioNum != 20 && gpioNum != 1 && gpioNum != 3)
		{
				printf("gpioNum != 20 || gpioNum != 1 || gpioNum != 3 ! gpioNum  = %d\n", gpioNum);	
				return -4;
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData + 1, 4);	
		
		unsigned char data = (unsigned char)GetGpio(gpioNum);
		
		unsigned char dataDirection = 0x01;
		unsigned short dataLen = 6;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, pFilter->dataLen+1);
		
		unsigned char checkCode = 0;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + 6;
		for(unsigned char i=0; i<headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		recvData->buf[headLen] = gpioNum;
		recvData->buf[headLen + 1] = data;
		memcpy(recvData->buf + headLen + 2, privateData, 4);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
}

static int SetGpio(unsigned int key,unsigned int value)
{
		if( fd < 0 ) 
		{
				fd = open("/dev/dev_rk_gpio",O_RDWR|O_NOCTTY);
				if(fd < 0)
				{
						writeLog("SetGpio:fd < \n", __FILE__, __LINE__);
						return -1;
				}
		}
		return ioctl (fd, key, value);
}

static int GetGpio(unsigned int key)
{
		if( fd < 0 ) 
		{
				writeLog("GetGpio:fd == -1\n", __FILE__, __LINE__);
				if(fd < 0)
				{
						writeLog("GetGpio:fd < 0\n", __FILE__, __LINE__);
						return -1;
				}
				return -1;
		}
		return ioctl (fd, key, 0x10);
}


static int fakeReadData(unsigned int checkKeyNumber)
{
		static int returnTimes = 0;
		returnTimes ++;
		if(returnTimes % 9 < 4)
		{
				return 1;
		}
		else
		{
				return 0;	
		}	
} 


/*static void* gpioStatusCheckThread(void *arg)
{
		static bool buttonIsTouching = false;
		
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		int buttonStatus = 0;
		int lastButtonStatus = 0;
		
		if( sem_init(&(sem_tmp), 1, 0) != 0   ) 
		{
				printf("sem_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}

		while( !IsExit() )
		{
				gettimeofday(&tv, NULL); 
				
			  ts.tv_sec  = tv.tv_sec + 1;
		    ts.tv_nsec = tv.tv_usec * 1000;		
		    
		    sem_timedwait(&(sem_tmp),&ts);
		    
		    buttonStatus = GetGpio(CHECK_KEY_NUMBER);
		    //buttonStatus = fakeReadData(CHECK_KEY_NUMBER);
		    //printf("buttonStatus = %d\n", buttonStatus);
		    if(buttonStatus == _buttonDown && lastButtonStatus == _buttonDown)
		    {
		    		if(buttonIsTouching == false)
		    		{
		    				if(pgSystemParam->centerCtrlMachineIsOpen == true)
				    		{
				    				pgSystemParam->centerCtrlMachineIsOpen = false;	
				    				closeCenterCtrlMachine();
				    		}
				    		else
				    		{
				    				pgSystemParam->centerCtrlMachineIsOpen = true;	
				    				openCenterCtrlMachine();
				    		}
				    		buttonIsTouching = true;
		    		}
		    }
		    else
		    {
		    		buttonIsTouching = false;
		    } 
		    
		    lastButtonStatus = buttonStatus;
		}	
		
		return NULL;
}*/


//20160530 change
#define CHECK_KEY_NUMBER 4
enum _buttonStatus
{
		_default = 0xFF,
		_noDevice = 1,
		_buttonUp = 1,
		_buttonDown = 0,
};
typedef enum _outSysStatus
{
		_normal = 0,//belong to open or close
		_opening,//belong to open
		_closing,//belong to close	
}OutSysStatus;
#define AMPLIFIER_IO_NUMBER 20
#define PROJECTOR_IO_NUMBER 5
#define NORMAL_DELAY_TIME 2
//#define AMPLIFIER_DELAY_TIME 15
//#define PROJECTOR_DELAY_TIME 180
static sem_t sem_open_out_sys;
static sem_t sem_close_out_sys;
static OutSysStatus outSysStatus = _normal;
static void* gpioStatusCheckThread(void *arg)
{
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		int buttonStatus = _default;
		int lastButtonStatus = _default;
		
		if( sem_init(&(sem_tmp), 1, 0) != 0 ) 
		{
				printf("sem_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}
		SetGpio(AMPLIFIER_IO_NUMBER, 1);
		SetGpio(PROJECTOR_IO_NUMBER, 1);
		
		buttonStatus = GetGpio(CHECK_KEY_NUMBER);
		//if the button status is _buttonDown when first time check, then open out sys directory
		/*if(buttonStatus == _buttonDown)
		{
				printf("if the button status is _buttonDown when first time check, then open out sys directory \n");
				sem_post(&sem_open_out_sys); 			
		    printf("send post open sem\n");	
		    pgSystemParam->outSysIsOpen = true;
		}
		else
		{
				pgSystemParam->outSysIsOpen = false;	
		}*/
		pgSystemParam->outSysIsOpen = false;	

		while( !IsExit() )
		{
				gettimeofday(&tv, NULL); 
				
			  ts.tv_sec  = tv.tv_sec + 1;
		    ts.tv_nsec = tv.tv_usec * 1000;		
		    
		    sem_timedwait(&(sem_tmp),&ts);
		    
		    buttonStatus = GetGpio(CHECK_KEY_NUMBER);
		    //buttonStatus = fakeReadData(CHECK_KEY_NUMBER);
		    //printf("buttonStatus = %d\n", buttonStatus);
		    
		    if(outSysStatus != _normal && outSysStatus != _opening && outSysStatus != _closing)
		    {
		    		char logBuf[128];
		    		sprintf(logBuf, "outSysStatus status machine error ! outSysStatus = %d\n", outSysStatus);	
		    		writeLog(logBuf, __FILE__, __LINE__);
		    		
		    		outSysStatus = _normal;
		    }
		    
		    if(outSysStatus == _normal)
		    {
				    if(buttonStatus == _buttonDown && lastButtonStatus == _buttonUp)
				    {
				    		//if(outSysStatus == _closing)
				    		//{
				    		//		sem_post(&sem_close_out_sys);
				    		//}
				    		if(pgSystemParam->outSysIsOpen == true)
								{
										writeLog("user want to open out sys pass button when out sys is open, we ignore the action !\n", __FILE__, __LINE__);	
										lastButtonStatus = buttonStatus;
										continue;
								}
		    				sem_post(&sem_open_out_sys); 			
		    				LOGD("user:send post open sem\n");	
				    }
				    else if(buttonStatus == _buttonUp && lastButtonStatus == _buttonDown)
				    {
				    		//if(outSysStatus == _opening)
				    		//{
				    		//		sem_post(&sem_open_out_sys);
				    		//}
				    		if(pgSystemParam->outSysIsOpen == false)
								{
										writeLog("user want to close out sys pass button when out sys is close, we ignore the action !\n", __FILE__, __LINE__);	
										lastButtonStatus = buttonStatus;
										continue;
								}
				    		sem_post(&sem_close_out_sys); 
				    		LOGD("user:send post close sem\n");		
				    } 
				}
				else
				{
						printf("opening or closing out sys, reject all other action !\n");	
				}
		    
		    lastButtonStatus = buttonStatus;
		}	
		
		return NULL;
}

static void *openOutSysThread(void *arg)
{
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		bool restart = false;
	
		if( sem_init(&(sem_open_out_sys), 1, 0) != 0 ) 
		{
				LOGD("sem_init failure \n");
				return NULL;
		}
	
		//for test
		//while(!IsExit())
		//{
		//		openProjector();
		//		sleep(5);
		//		closeProjector();		
		//		sleep(5);	
		//}
	
		while( !IsExit() )
		{
				if(restart == false)
				{
						gettimeofday(&tv, NULL); 
					  ts.tv_sec  = tv.tv_sec + 2;
				    ts.tv_nsec = tv.tv_usec * 1000;	
				    ret = sem_timedwait(&(sem_open_out_sys),&ts);
				    if(ret != 0) continue;
				}

				pgSystemParam->outSysIsOpen = true;
				setUserFirstOpenWifi();
				LOGD("start to open out sys\n");
				outSysStatus = _opening;
				SetGpio(PROJECTOR_IO_NUMBER, 0);
				printf("open:after set gpio PROJECTOR_IO_NUMBER\n");
				
				openWifi();
				
				gettimeofday(&tv, NULL); 
			  ts.tv_sec  = tv.tv_sec + NORMAL_DELAY_TIME;
		    ts.tv_nsec = tv.tv_usec * 1000;	
		    
		    writeSoftwareVersionToCfg(SOFTWARE_VERSION_VALUE);
		    
				ret = sem_timedwait(&(sem_open_out_sys),&ts);
				if(ret == 0) 
				{
						restart = true;
						LOGD("recv open_sem while opening ! prepare to restart !\n");
						continue;
				}
				
				if(outSysStatus != _opening)
				{
						restart = false;
						LOGD("outSysStatus != _opening while opening ! we stop the next open steps\n");
						continue;
				}
				SetGpio(AMPLIFIER_IO_NUMBER, 0);
				printf("open:after set gpio AMPLIFIER_IO_NUMBER\n");
				gettimeofday(&tv, NULL); 
				unsigned int dtime = (pgSystemParam->projectorSendOpenCodeDelayTime < 2 || pgSystemParam->projectorSendOpenCodeDelayTime > 255) ? 15 : pgSystemParam->projectorSendOpenCodeDelayTime;
			  ts.tv_sec  = tv.tv_sec + dtime;
		    ts.tv_nsec = tv.tv_usec * 1000;	
				ret = sem_timedwait(&(sem_open_out_sys),&ts);
				if(ret == 0)
				{
						restart = true;
						LOGD("recv open_sem while opening ! prepare to restart !\n");
						continue;
				}
				
				if(outSysStatus != _opening)
				{
						restart = false;
						LOGD("outSysStatus != _opening while opening ! we stop the next open steps\n");
						continue;
				}
				openProjector();
				outSysStatus = _normal;
				restart = false;
				LOGD("complete all open steps\n");
		}
		
		return NULL;
}

static void *closeOutSysThread(void *arg)
{
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		bool restart = false;
	
		if( sem_init(&(sem_close_out_sys), 1, 0) != 0 ) 
		{
				LOGD("sem_init failure \n");	
				return NULL;
		}
		
		while( !IsExit() )
		{
				if(restart == false)
				{
						gettimeofday(&tv, NULL); 
					  ts.tv_sec  = tv.tv_sec + 2;
				    ts.tv_nsec = tv.tv_usec * 1000;	
				    ret = sem_timedwait(&(sem_close_out_sys),&ts);
				    if(ret !=  0) continue;
				}
			
				pgSystemParam->outSysIsOpen = false;
				LOGD("start to close \n");
				outSysStatus = _closing;
				closeProjector();
				printf("after close projector\n");
				
				closeWifi();
				
				gettimeofday(&tv, NULL); 
			  ts.tv_sec  = tv.tv_sec + NORMAL_DELAY_TIME;
		    ts.tv_nsec = tv.tv_usec * 1000;	
				ret = sem_timedwait(&(sem_close_out_sys),&ts);
				if(ret == 0) 
				{
						restart = true;
						LOGD("recv close_sem while closing ! prepare to restart !\n");
						continue;
				}
		
				if(outSysStatus != _closing)
				{
						restart = false;
						printf("set restart == true {%s,%d}\n", __FILE__, __LINE__);
						continue;	
				}
				SetGpio(AMPLIFIER_IO_NUMBER, 1);
				printf("close:after set gpio AMPLIFIER_IO_NUMBER\n");
				gettimeofday(&tv, NULL); 
			  ts.tv_sec  = tv.tv_sec + pgSystemParam->projectorCutOffElectricityDelayTime;
		    ts.tv_nsec = tv.tv_usec * 1000;	
				ret = sem_timedwait(&(sem_close_out_sys),&ts);
				if(ret == 0) 
				{
						restart = true;
						LOGD("recv close_sem while closing ! prepare to restart !\n");
						continue;
				}
				
				if(outSysStatus != _closing)
				{
						restart = false;
						LOGD("outSysStatus != _closing while opening ! we stop the next open steps\n");
						continue;	
				}
				SetGpio(PROJECTOR_IO_NUMBER, 1);
				outSysStatus = _normal;
				
				LOGD("complete close out sys ! prepare to reboot !");
		    reboot();
		}
		
		return NULL;
}


int cmdOpenOutSys()
{
		if(pgSystemParam->outSysIsOpen == true)
		{
				writeLog("client want to open out sys when out sys is open, we ignore the action !\n", __FILE__, __LINE__);	
				return -4;
		}
		
		int ret = -10;
		char logBuf[128];
		switch(outSysStatus)
		{
				case _normal:
						sem_post(&sem_open_out_sys); 			
			    	writeLog("cmd:send post open sem\n", __FILE__, __LINE__);	
			    	ret = 0;
			    	break;
		    case _opening:
			    	sprintf(logBuf, "cmd:opening out sys, reject all other action ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	ret = -1;
			    	break;
		   	case _closing:
			    	sprintf(logBuf, "cmd:closing out sys, reject all other action ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	ret = -2;
			    	break;
		    default:
			    	sprintf(logBuf, "outSysStatus status machine error ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	outSysStatus = _normal;
			    	ret = -3;
			    	break;	
		}
	
		return ret;
}

int cmdCloseOutSys()
{
		if(pgSystemParam->outSysIsOpen == false)
		{
				writeLog("client want to close out sys when out sys is close, we ignore the action !\n", __FILE__, __LINE__);	
				return -4;
		}
	
		int ret = -10;
		char logBuf[128];
		switch(outSysStatus)
		{
				case _normal:
						sem_post(&sem_close_out_sys); 			
			    	writeLog("cmd:send post close sem\n", __FILE__, __LINE__);	
			    	ret = 0;
			    	break;
		    case _opening:
			    	sprintf(logBuf, "cmd:opening out sys, reject all other action ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	ret = -1;
			    	break;
		   	case _closing:
			    	sprintf(logBuf, "cmd:closing out sys, reject all other action ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	ret = -2;
			    	break;
		    default:
			    	sprintf(logBuf, "outSysStatus status machine error ! outSysStatus = %d\n", outSysStatus);	
			    	writeLog(logBuf, __FILE__, __LINE__);
			    	outSysStatus = _normal;
			    	ret = -3;
			    	break;	
		}
	
		return ret;
}

int cmdOutSysToggle()
{
		if(outSysStatus == _opening)
		{
			LOGD("outSysStatus is opening, we ignore the ir toggle action !\n");
		}
		else if(outSysStatus == _closing)
		{
			LOGD("outSysStatus is closing, we ignore the ir toggle action !\n");
		}
		else
		{
			if(pgSystemParam->outSysIsOpen == true) 
			{
				cmdCloseOutSys();
			}
			else 
			{
				cmdOpenOutSys();
			}
		}
}

void openProjectorNice()
{
		if(GetGpio(PROJECTOR_IO_NUMBER) == 1)
		{
				unsigned int dtime = (pgSystemParam->projectorSendOpenCodeDelayTime < 2 || pgSystemParam->projectorSendOpenCodeDelayTime > 255) ? 15 : pgSystemParam->projectorSendOpenCodeDelayTime;
				char logBuf[128];
				sprintf(logBuf, "openProjectorNice: prepare to delay org,real = %d,%d\n", pgSystemParam->projectorSendOpenCodeDelayTime,dtime);
				LOGD(logBuf);
				SetGpio(PROJECTOR_IO_NUMBER, 0);
				sleep(dtime);
		}

		openProjector();
}



//add 20160715
#define STATUS_KEY_NUMBER 3
#define LED_ON 1
#define LED_OFF 0

static void* ledThread(void* arg)
{
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		
		if( sem_init(&(sem_tmp), 1, 0) != 0 ) 
		{
				printf("sem_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}
		
		printf("prepare to set led status\n");
		closeLed(STATUS_KEY_NUMBER);

		while( !IsExit() )
		{
				gettimeofday(&tv, NULL); 
				
			  ts.tv_sec  = tv.tv_sec + 1;
		    ts.tv_nsec = tv.tv_usec * 1000;		
		    
		    sem_timedwait(&(sem_tmp),&ts);
		    
		    if(outSysStatus == _opening)
		    {
		    		ledShowOutSysOpening(STATUS_KEY_NUMBER);
		    }
		    else if(outSysStatus == _closing)
		    {
		    		ledShowOutSysClosing(STATUS_KEY_NUMBER);
		    }
		    else
		    {
		    		closeLed(STATUS_KEY_NUMBER);
		    }
		}
	
		return NULL;
}

static void ledShowOutSysOpening(int led)
{
		//printf("into ledShowOutSysOpening\n");
		openLed(led);
}

static void ledShowOutSysClosing(int led)
{
		//printf("into ledShowOutSysClosing\n");
		overReturnLed(led);
}

static void openLed(int led)
{
		SetGpio(led, LED_ON);
}

static void closeLed(int led)
{
		SetGpio(led, LED_OFF);
}

static void overReturnLed(int led)
{
		int nowStatus = GetGpio(led);
		if(nowStatus) nowStatus = 1;
		int nextStatus = 1 - nowStatus;
		SetGpio(led, nextStatus);
		//printf("nowStatus,nextStatus=%d,%d\n", nowStatus,nextStatus);
}


